package com.zhiwei.codesecurity.redis;

import com.alibaba.fastjson.JSON;
import com.zhiwei.codesecurity.common.domain.Param;
import com.zhiwei.codesecurity.common.utils.StringUtils;
import com.zhiwei.codesecurity.service.redis.IJedisClientUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class JedisClientUserServiceImpl implements IJedisClientUserService {
    private static  final Logger logger = LoggerFactory.getLogger(JedisClientUserServiceImpl.class);

    @Autowired
    private JedisPool jedisPool;

    @Override
    public boolean get(Param p, int expire)  {
        Jedis jedisSingle = jedisPool.getResource();
        String key = new StringBuffer().append(p.getBid()).append("-").append(p.getUid()).toString();
        try {
            // redis中获取该用户下面所有的token信息
            String value = jedisSingle.get(key);
            if (StringUtils.isBlank(value)) {
                return false;
            }

            List<Param> list = JSON.parseArray(value, Param.class);
            if (null == list || list.size() == 0) {
                logger.info(">>>>>>>>>>{}, {}, 令牌不存在!<<<<<<<<<<<<", key, p.getTokenId());
                return false;
            }

            Param pt = null;
            int i = 0;
            for (; i < list.size(); i++) {
                if (list.get(i).getTokenId().equals(p.getTokenId())) {
                    pt = list.get(i);
                    break;
                }
            }

            // 令牌不存在
            if (null == pt) {
                logger.info(">>>>>>>>>>{}, {}, 令牌不存在!<<<<<<<<<<<<", key, p.getTokenId());
                return false;
            }

            // 判断登录态是否超时
            long time = new Date().getTime() - pt.getDate().getTime();
            if (time > expire * 60 * 1000) {    // expire为过期时间，单位为：分钟
                list.remove(i);
                if (list.size() == 0) {
                    jedisSingle.del(key);
                } else {
                    value = JSON.toJSONString(list);
                    jedisSingle.set(key, value);
                }
                logger.info(">>>>>>>>>>{}, {}, 令牌已经过期!<<<<<<<<<<<<", key, p.getTokenId());
                return false;
            }

            // 自动延长过期时间
            list.remove(i);
            pt.setDate(new Date());
            list.add(pt);
            jedisSingle.set(key, JSON.toJSONString(list));
            logger.info(">>>>>>>>>>{}, {}, 获取成功:{}<<<<<<<<<<<<", key, p.getTokenId(), pt.toString());
            return true;
        } catch (Exception ex) {
            logger.info(">>>>>>>>>>{}, {}, 异常报错:{}<<<<<<<<<<<<", key, p.getTokenId(), ex.getMessage());
            return false;
        } finally {
            jedisSingle.close();
        }
    }

    @Override
    public void set(Param p) {
        Jedis jedisSingle = jedisPool.getResource();
        try {
            String key = new StringBuffer().append(p.getBid()).append("-").append(p.getUid()).toString();
            // 取出该用户的所有令牌
            String value = jedisSingle.get(key);
            List<Param> list = new ArrayList<>();
            if (!StringUtils.isBlank(value)) {
                list = JSON.parseArray(value, Param.class);
            }

            // 新增登录令牌
            list.add(p);
            jedisSingle.set(key, JSON.toJSONString(list));
            logger.info(">>>>>>>>>>{}, {}, 存入redis成功<<<<<<<<<<<", key, p.toString());
        } catch (Exception ex) {
            logger.info(">>>>>>>>>>{}, {}, 存入redis中出错:{}<<<<<<<<<<<", p.getBid() + p.getUid() ,p.toString(),
                    ex.getMessage());
        } finally {
            jedisSingle.close();
        }
    }

    @Override
    public void del(Param p) {
        Jedis jedisSingle = jedisPool.getResource();
        String key = new StringBuffer().append(p.getBid()).append("-").append(p.getUid()).toString();
        try {
            String value = jedisSingle.get(key);
            if (StringUtils.isBlank(value)) {
                return;
            }
            List<Param> list = JSON.parseArray(value, Param.class);
            if (null == list || list.size() == 0) {
                return;
            }
            String source = p.getSource();
            if (StringUtils.isBlank(source)) {
                return;
            }

            List<Param> newList = new ArrayList<>();
            Param tmp;
            for (int i = 0; i < list.size(); i++) {
                tmp = list.get(i);
                if (!source.equals(tmp.getSource())) {
                    newList.add(tmp);
                }
            }

            if (newList.size() == 0) {
                jedisSingle.del(key);
            } else {
                value = JSON.toJSONString(newList);
                jedisSingle.set(key, value);
            }
            logger.info(">>>>>>>>>>{}, {}, 删除成功<<<<<<<<<<<", key, p.toString());
        } catch (Exception ex) {
            logger.info(">>>>>>>>>>{}, {}, 删除报错:{}<<<<<<<<<<<", key, p.toString(), ex.getMessage());
        } finally {
            jedisSingle.close();
        }
    }

    @Override
    public void delayToken(Param p) {
        Jedis jedisSingle = jedisPool.getResource();
        String key = new StringBuffer().append(p.getBid()).append("-").append(p.getUid()).toString();
        try {
            String value = jedisSingle.get(key);
            if (StringUtils.isBlank(value)) {
                return;
            }
            List<Param> list = JSON.parseArray(value, Param.class);
            if (null == list || list.size() == 0) {
                return;
            }
            boolean flag = false;
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).getTokenId().equals(p.getTokenId())) {
                    list.remove(i);
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                return;
            }
            list.add(p);
            value = JSON.toJSONString(list);
            jedisSingle.set(key, value);
            logger.info(">>>>>>>>>>{}, {}, token延期成功<<<<<<<<<<<", key, p.toString());
        } catch (Exception ex) {
            logger.info(">>>>>>>>>>{}, {}, token延期报错:{}<<<<<<<<<<<", key, p.toString(), ex.getMessage());
        } finally {
            jedisSingle.close();
        }
    }

    @Override
    public void deleteAllTokensByKey(Param p) {
        Jedis jedisSingle = jedisPool.getResource();
        String key = new StringBuffer().append(p.getBid()).append("-").append(p.getUid()).toString();
        try {
            // 先删除key下面所有令牌
            jedisSingle.del(key);
            logger.info(">>>>>>>>>>{},删除用户所有token成功<<<<<<<<<<<", key);
            if (!StringUtils.isBlank(p.getTokenId())) {
                List<Param> list = new ArrayList<Param>();
                // 新增当前登录令牌
                list.add(p);
                jedisSingle.set(key, JSON.toJSONString(list));
                logger.info(">>>>>>>>>>{},{},存入redis成功<<<<<<<<<<<", key, p.toString());
            }
        } catch (Exception ex) {
            logger.info(">>>>>>>>>>{},删除用户所有token报错:{}<<<<<<<<<<<", key, ex.getMessage());
        } finally {
            jedisSingle.close();
        }
    }
}
